package com.tedu.api.io;

import org.junit.Test;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.sql.SQLOutput;
import java.util.Random;

/**
 * RandomAccessFile专门解决：File无法实现读写操作
 *
 * RandomAccessFile类   随机访问文件类
 * 功能：实现文件、文件夹读写操作，接近底层，底层使用C语言编写，底层以二进制数据形式为核心
 *
 * 创建随机访问文件类
 * RandomAccessFile   raf=new RandomAccessFile("路径+文件全称""rw")
 * RandomAccessFile   raf=new RandomAccessFile("路径+文件全称""r")
 * 第二个参数[mode 模式]：r模式--->该文件可以读操作
 *                     rw模式--->该文件可以读写操作
 * 需求 实现CV  复制音乐/视频
 */
public class RandomAccessFileAPI {
    @Test
    public void testRaf() throws IOException {
        //RandomAccessFile对象创建出来---路径+全程  | 模式："rw"
        RandomAccessFile raf=new RandomAccessFile("raf.txt","rw");
        //1.在API  项目文件夹下 创建raf.txt 文件，并实现读写操作

        //计算机 识别 ： 二进制  0000 0000
        /**
         * 需要往raf.txt 写一个字母 a
         * write(整数:十进制)  十进制 转换为计算机识别二进制
         *       范围：0~255  ASCII码  二进制---十进制---字母
         *                                      97     a
         *                                      98     b
         * 作用：往文件中写出一个字节，抛出IO流异常：存在写入失败的情况
         *      整数的低八位写出到文件中
         *      一个字节==八位二进制     0000 0001   1
         *                            0000 0010   2
         *                            0000 0011   3
         *                            0000 0110   6
         *       1024字节==1KB
         *       1024KB==1MB
         *       1024MB==1GB
         *       1024GB==1TB
         */
        raf.write(97);  //写出：一个字节，识别二进制，写十进制转二进制
        raf.write(98);
        raf.write(101);
        //write方法---一个字节一个字节写出
        //关闭流   close
        raf.close();
    }

    /**
     * read()
     * 作用：读取一个字节，返回十进制 int类型返回，如果文件读到-1，代表结束
     */
    @Test
    public void testRead() throws IOException {
        //创建对象：随机访问文件的对象--只读操作---raf.txt文件的内容
        RandomAccessFile raf=new RandomAccessFile("raf.txt","r");
        int i=raf.read();  //"a"---ASCII码---97
        int j=raf.read();  //"b"---ASCII码---98
        int k=raf.read();  //"e"---ASCII码---101
        int y=raf.read();  //-1  代表  文件没有数据
        System.out.println(i+" "+j+" "+k+" "+y);

    }

    /**
     * RAF类---构造器实现：读写操作---write(数值) read() 一个字节一个字节写出以及读入
     * 复制粘贴一个音乐 【version  1---不考虑效率】
     */
    @Test
    public void testCV() throws IOException {
        //1.源文件--”知更鸟 _ HOYO-MiX _ Chevy - 在银河中孤独摇摆 (320CBR).mp3“  --复制--操作：读入
        RandomAccessFile src=
                new RandomAccessFile
                        ("知更鸟 _ HOYO-MiX _ Chevy - 在银河中孤独摇摆 (320CBR).mp3","r");
        //2.复制文件--”在银河中孤独摇摆.mp3“  --粘贴--操作：写出
        RandomAccessFile desc=new RandomAccessFile("在银河中孤独摇摆.mp3","rw");
        //3.用于保存读取到的字节：①保存一个字节 ②-1代表文件读到末尾
        int data=-1;
        //4.从”知更鸟 _ HOYO-MiX _ Chevy - 在银河中孤独摇摆 (320CBR).mp3“中一个字节一个字节读取--
        //同时一个字节一个字节写出”在银河中孤独摇摆.mp3“
        //(data=src.read())!=-1  条件判断语句
        long start=System.currentTimeMillis();//获取到当前系统时间毫秒数
        while((data=src.read())!=-1){//一个字节一个字节--读
            //同时一个字节一个字节写出”在银河中孤独摇摆.mp3“
            desc.write(data);
        }
        long end=System.currentTimeMillis();
        System.out.println("复制粘贴花费的时间："+(end-start)/1000+"秒");
    }
    /**
     * 需求：复制粘贴一个音乐 【version  1 --考虑效率】
     * 一个字节一个字节读取---一个字节一个字节写出【慢】
     * 100KB读取---100KB写出   【快】
     */
    @Test
    public void testCVS() throws IOException {
        //1.从API目录下“小跳蛙.mp3”读取数据【100KB】
        RandomAccessFile raf=new RandomAccessFile("知更鸟 _ HOYO-MiX _ Chevy - 在银河中孤独摇摆 (320CBR).mp3","r");
    //2.从API目录下写出“效率高.mp3”--写出数据【100KB】
    RandomAccessFile desc=new RandomAccessFile("效率高.mp3","rw");
    //3.保存每次读取字节量：①覆盖：保存读写数据，保障数据稳定
    //                  ②没有数据：表示文件读取到末尾
    int len=-1;
    //4.效率：100KB   字节数组：byte
    byte[] data=new byte[1024*100];//100KB
    //5.从src文件中读取数据：100KB   |  read(byte[] b)  读100KB
    //5.1  src.read()      从src”小跳蛙.mp3“   100KB的读
    //5.2  src.read(byte[] data)  从src”小跳蛙.mp3“  100KB的读
    //5.3  len=src.read(byte[] data)  保存从src”小跳蛙.mp3“ 100KB的读
    //5.4  (len=src.read(byte[] data))!=-1 【复制判断条件】
    //     将读到的100KB的字节数据保存到len中，只要不等于-1没有读完，一直读
    long start=System.currentTimeMillis();
    while( (len=raf.read(data)) !=-1) {
        // 同时，读文件的同时，写出数据
        //write() 写出一个字节【慢】
        //write(字节数组,0,-1) 写出字节数组指定的单位量【例如：100KB】
        desc.write(data, 0, len);
       }
    long end=System.currentTimeMillis();
    System.out.println("100KB复制版本：" + (end - start) + "毫秒数");
    }
    @Test
    public void testCVVideo() throws IOException {
        RandomAccessFile raf=new RandomAccessFile("视频.mp4","r");
        RandomAccessFile desc=new RandomAccessFile("新视频.mp4","rw");
        int len=-1;  byte[] data=new byte[1024*100];
        long start=System.currentTimeMillis();
        while( (len=raf.read(data)) !=-1) {
            desc.write(data, 0, len);
        }
        long end=System.currentTimeMillis();
        System.out.println("100KB复制版本：" + (end - start) + "毫秒数");
    }
}

